import tester.cobertura.Instrument;

/**
 * @author Adam Blackwell & Ryan Cassidy
 */
// to represent a bank account
@Instrument 
abstract class AAccount implements IAccount {

	public int accountNum; // Must be unique
	public int balance; // Must remain above zero
	public String name; // The name of account

	AAccount(int accountNum, int balance, String name) {
		this.accountNum = accountNum;
		this.balance = balance;
		this.name = name;
	}

	// produce an updated account after depositing the given amount
	public abstract IAccount deposit(int amt);

	// produce an updated account after withdrawing the given amount
	public abstract IAccount withdraw(int amt);

	// Checks if you can withdraw a certain amount.
	public boolean canWithdraw(int amt) {
		return amt <= this.balance;
	}

	// Checks if two accounts are the same.
	public abstract boolean same(IAccount act);

	// Checks if this account is a Checking account.
	public boolean isChecking() {
		return false;
	}

	// Checks if this account is a Credit account.
	public boolean isCredit() {
		return false;
	}

	// Checks if this account is a Savings account.
	public boolean isSavings() {
		return false;
	}

	// Turns the account into a Checking account.
	public Checking toChecking() {
		throw new RuntimeException("This is the wrong type of account");
	}

	// Turns the account into a Credit account.
	public Credit toCredit() {
		throw new RuntimeException("This is the wrong type of account");
	}

	// Turns the account into a Savings account.
	public Savings toSavings() {
		throw new RuntimeException("This is the wrong type of account");
	}

	// Checks if this account is a PremiumChecking account
	public boolean isPremiumChecking() {
		return false;
	}

	// Turns the account into a PremiumChecking account.
	public PremiumChecking toPremiumChecking() {
		throw new RuntimeException("This is the wrong type of account");
	}

	/*
	 * 3. See what changes can you make to the withdraw method.  Make the
	 * exception report the name on the account when the exception indicates
	 * that a withdrawal is not possible.  Explain why we could not do this
	 * before defining the abstract class? (We could, but it would involve extra
	 * work.)
	 * 
	 * I don't know? accessibility of name?
	 * 
	 *  Explain why we cannot define a concrete method withdraw in the abstract
	 * class Account.
	 * 
	 * For each type of account the return type is different.
	 * 
	 * /
	 */
}